home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 176-200 / disk_190 / nethack / twee.zoo / do.c < prev    next >
C/C++ Source or Header  |  1988-07-28  |  12KB  |  541 lines

  1. /*    SCCS Id: @(#)do.c       2.3     88/02/11
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3.  
  4. /* Contains code for 'd', 'D' (drop), '>', '<' (up, down) and 't' (throw) */
  5.  
  6. #include "hack.h"
  7.  
  8. extern struct obj *splitobj(), *addinv();
  9. extern boolean hmon();
  10. extern boolean level_exists[];
  11. extern struct monst youmonst;
  12. extern char *Doname();
  13. extern char *nomovemsg;
  14. int    identify();
  15. #ifdef KAA
  16. extern char *xname();
  17. #endif
  18.  
  19. dodrop() {
  20.     if(u.ugold)     return(drop(getobj("0$#", "drop")));
  21.     else        return(drop(getobj("0#", "drop")));
  22. }
  23.  
  24. static
  25. drop(obj) register struct obj *obj; {
  26.     if(!obj) return(0);
  27.     if(obj->olet == GOLD_SYM) {             /* pseudo object */
  28.         register long amount = OGOLD(obj);
  29.  
  30.         if(amount == 0)
  31.             pline("You didn't drop any gold pieces.");
  32. /* Fix bug with dropping huge amounts of gold read as negative      KAA */
  33.         else if(amount < 0) {
  34.             u.ugold += amount;
  35.     pline("The LRS would be very interested to know you have that much.");
  36.         } else {
  37.             /* uswallow test added by GAN 01/29/87 */
  38.             pline("You dropped %ld gold piece%s.",
  39.                  amount, plur(amount));
  40.             if(u.uswallow)
  41.                 (u.ustuck)->mgold += amount;
  42.             else {
  43.                 mkgold(amount, u.ux, u.uy);
  44.                 if(Invisible) newsym(u.ux, u.uy);
  45.             }
  46.         }
  47.         free((char *) obj);
  48.         return(1);
  49.     }
  50.     if(obj->owornmask & (W_ARMOR | W_RING | W_TOOL)){
  51.         pline("You cannot drop something you are wearing.");
  52.         return(0);
  53.     }
  54.     if(obj == uwep) {
  55.         if(uwep->cursed) {
  56.             pline("Your weapon is welded to your hand!");
  57.             return(0);
  58.         }
  59.         setuwep((struct obj *) 0);
  60.     }
  61. #ifdef WALKIES
  62.     if (obj->otyp == LEASH) {
  63.         register struct monst *mtmp = fmon;
  64.         while (mtmp && !mtmp->mleashed) mtmp = mtmp->nmon;
  65.         if (mtmp) {
  66.         pline ("Your leash is tied around your hand.");
  67.         return (0);
  68.         }
  69.     }
  70. #endif
  71. #ifdef SINKS
  72.     if((obj->olet == RING_SYM) && IS_SINK(RM_TYP(levl[u.ux][u.uy])))
  73.         if (u.uswallow) {
  74.         freeinv(obj);
  75.         mpickobj(u.ustuck,obj);
  76.         return(1);
  77.         }
  78.         else {
  79.         dosinkring(obj);
  80.         return(1);
  81.         }
  82. #endif
  83.     pline("You dropped %s.", doname(obj));
  84.     dropx(obj);
  85.     return(1);
  86. }
  87.  
  88. /* Called in several places - should not produce texts */
  89. dropx(obj)
  90. register struct obj *obj;
  91. {
  92.     freeinv(obj);
  93.     dropy(obj);
  94. }
  95.  
  96. dropy(obj)
  97. register struct obj *obj;
  98. {
  99.     if(obj->otyp == CRYSKNIFE)
  100.         obj->otyp = WORM_TOOTH;
  101.     /* uswallow check done by GAN 01/29/87 */
  102.     if(u.uswallow)
  103.         mpickobj(u.ustuck,obj);
  104.     else  {
  105.         obj->ox = u.ux;
  106.         obj->oy = u.uy;
  107.         /* Blind check added by GAN 02/18/87 */
  108.         if(Blind)  {
  109. #ifdef KAA
  110.             if(obj->olet != ')')
  111. #endif
  112.                 obj->dknown = index("/=!?*",obj->olet) ? 0 : 1;
  113.             obj->known = 0;
  114.         }
  115.         obj->nobj = fobj;
  116.         fobj = obj;
  117.         if(Invisible) newsym(u.ux,u.uy);
  118.         subfrombill(obj);
  119.         stackobj(obj);
  120.     }
  121. }
  122.  
  123. /* drop several things */
  124. doddrop() {
  125.     return(ggetobj("drop", drop, 0));
  126. }
  127.  
  128. dodown()
  129. {
  130.     if(u.ux != xdnstair || u.uy != ydnstair) {
  131.         pline("You can't go down here.");
  132.         return(0);
  133.     }
  134.     if(u.ustuck) {
  135.         pline("You are being held, and cannot go down.");
  136.         return(1);
  137.     }
  138.     if(Levitation) {
  139.         pline("Your floating high above the stairs.");
  140.         return(0);
  141.     }
  142.  
  143.     goto_level(dlevel+1, TRUE);
  144.     return(1);
  145. }
  146.  
  147. doup()
  148. {
  149.     if(u.ux != xupstair || u.uy != yupstair) {
  150.         pline("You can't go up here.");
  151.         return(0);
  152.     }
  153.     if(u.ustuck) {
  154.         pline("You are being held, and cannot go up.");
  155.         return(1);
  156.     }
  157.     if(!Levitation && inv_weight() + 5 > 0) {
  158.         pline("Your load is too heavy to climb the stairs.");
  159.         return(1);
  160.     }
  161.  
  162.     goto_level(dlevel-1, TRUE);
  163.     return(1);
  164. }
  165.  
  166. goto_level(newlevel, at_stairs)
  167. register int newlevel;
  168. register boolean at_stairs;
  169. {
  170.     register fd;
  171.     register boolean up = (newlevel < dlevel);
  172.  
  173.     if(newlevel <= 0) done("escaped");    /* in fact < 0 is impossible */
  174.     if(newlevel > MAXLEVEL) newlevel = MAXLEVEL;    /* strange ... */
  175.     if(newlevel == dlevel) return;        /* this can happen */
  176.  
  177.     glo(dlevel);
  178. #ifdef DGK
  179.     /* Use O_TRUNC to force the file to be shortened if it already
  180.      * exists and is currently longer.
  181.      */
  182.     fd = open(lock, O_WRONLY | O_BINARY | O_CREAT | O_TRUNC, FMASK);
  183. #else
  184.     fd = creat(lock, FMASK);
  185. #endif
  186.     if(fd < 0) {
  187.         /*
  188.          * This is not quite impossible: e.g., we may have
  189.          * exceeded our quota. If that is the case then we
  190.          * cannot leave this level, and cannot save either.
  191.          * Another possibility is that the directory was not
  192.          * writable.
  193.          */
  194. #ifdef DGK
  195.         pline("Cannot create level file '%s'.", lock);
  196. #else
  197.         pline("A mysterious force prevents you from going %s.",
  198.             up ? "up" : "down");
  199. #endif
  200.         return;
  201.     }
  202.  
  203. #ifdef DGK
  204.     if (!savelev(fd, dlevel, COUNT)) {
  205. # ifdef COMPRESS
  206.         bflush(fd);
  207. # endif
  208.         (void) close(fd);
  209.         (void) unlink(lock);
  210.         pline("HACK is out of disk space for making levels!");
  211.         pline("You can save, quit, or continue playing.");
  212.         return;
  213.     }
  214. #endif
  215.     if(Punished) unplacebc();
  216.     u.utrap = 0;                /* needed in level_tele */
  217.     u.ustuck = 0;                /* idem */
  218.     keepdogs();
  219.     seeoff(1);
  220.     if(u.uswallow)                          /* idem */
  221.         u.uswldtim = u.uswallow = 0;
  222.     flags.nscrinh = 1;
  223.     u.ux = FAR;                /* hack */
  224.     (void) inshop();                        /* probably was a trapdoor */
  225.  
  226. #ifdef DGK
  227. # ifdef COMPRESS
  228.     bflush(fd); /* Forget buffer */
  229. # endif
  230.     savelev(fd,dlevel, WRITE);
  231. #else
  232.     savelev(fd,dlevel);
  233. #endif
  234. #ifdef COMPRESS
  235.     bflush(fd); /* Flush buffer */
  236. #endif
  237.     (void) close(fd);
  238.  
  239.     dlevel = newlevel;
  240.     if(maxdlevel < dlevel)
  241.         maxdlevel = dlevel;
  242.     glo(dlevel);
  243. #ifdef MSDOS
  244.     /* If the level has no where yet, it hasn't been made
  245.      */
  246.     if(!fileinfo[dlevel].where)
  247. #else
  248.     if(!level_exists[dlevel])
  249. #endif
  250.         mklev();
  251.     else {
  252.         extern int hackpid;
  253. #ifdef DGK
  254.         /* If not currently accessible, swap it in.
  255.          */
  256.         if (fileinfo[dlevel].where != ACTIVE)
  257.             swapin_file(dlevel);
  258.  
  259.         if((fd = open(lock, O_RDONLY | O_BINARY)) < 0) {
  260. #else
  261.         if((fd = open(lock,0)) < 0) {
  262. #endif
  263.             pline("Cannot open %s .", lock);
  264.             pline("Probably someone removed it.");
  265.             done("tricked");
  266.         }
  267. #ifdef COMPRESS
  268.         minit();
  269. #endif
  270.         getlev(fd, hackpid, dlevel);
  271.         (void) close(fd);
  272.     }
  273.  
  274.     if(at_stairs) {
  275.         if(up) {
  276.         u.ux = xdnstair;
  277.         u.uy = ydnstair;
  278.         if(!u.ux) {             /* entering a maze from below? */
  279.             u.ux = xupstair;    /* this will confuse the player! */
  280.             u.uy = yupstair;
  281.         }
  282. /* Remove bug which crashes with levitation/punishment    KAA */
  283.         if(Punished) {
  284.             if(!Levitation)
  285.             pline("With great effort you climb the stairs.");
  286.             placebc(1);
  287.         }
  288.         } else {
  289.         u.ux = xupstair;
  290.         u.uy = yupstair;
  291.         if(inv_weight() + 5 > 0 || Punished){
  292.             pline("You fall down the stairs.");     /* %% */
  293.             losehp(rnd(3), "fall");
  294.             if(Punished) {
  295.                 if(uwep != uball && rn2(3)){
  296.                 pline("... and are hit by the iron ball.");
  297.                 losehp(rnd(20), "iron ball");
  298.                 }
  299.                 placebc(1);
  300.             }
  301.             selftouch("Falling, you");
  302.         }
  303.         }
  304.         { register struct monst *mtmp = m_at(u.ux, u.uy);
  305.           if(mtmp)
  306.         mnexto(mtmp);
  307.         }
  308.     } else {    /* trapdoor or level_tele */
  309.         do {
  310.         u.ux = rnd(COLNO-1);
  311.         u.uy = rn2(ROWNO);
  312.         } while(RM_TYP(levl[u.ux][u.uy]) != ROOM ||
  313.             m_at(u.ux,u.uy));
  314.         if(Punished){
  315.         if(uwep != uball && !up /* %% */ && rn2(5)){
  316.             pline("The iron ball falls on your head.");
  317.             losehp(rnd(25), "iron ball");
  318.         }
  319.         placebc(1);
  320.         }
  321.         selftouch("Falling, you");
  322.     }
  323.     (void) inshop();
  324.     initrack();
  325.  
  326.     losedogs();
  327.     { register struct monst *mtmp;
  328.       if(mtmp = m_at(u.ux, u.uy)) mnexto(mtmp);     /* riv05!a3 */
  329.     }
  330.     flags.nscrinh = 0;
  331.     setsee();
  332.     seeobjs();      /* make old cadavers disappear - riv05!a3 */
  333.     docrt();
  334.     pickup(1);
  335.     read_engr_at(u.ux,u.uy);
  336. }
  337.  
  338. donull() {
  339.     return(1);      /* Do nothing, but let other things happen */
  340. }
  341.  
  342. /* #if defined(KAA) && defined(KOPS) */
  343. #ifdef KAA
  344. # ifdef KOPS
  345. wipeoff()
  346. {
  347.     if(u.ucreamed < 4)      u.ucreamed = 0;
  348.     else            u.ucreamed -= 4;
  349.     if(u.ucreamed > 0)  {
  350.         Blinded -= 4;
  351.         if(Blind <= 1) {
  352.             pline("You've got the glop off.");
  353.             u.ucreamed = 0;
  354.             Blinded = 1;
  355.             return(0);
  356.         }
  357.         return(1);              /* still busy */
  358.     }
  359.     pline("Your face feels clean now.");
  360.     u.ucreamed = 0;
  361.     return(0);
  362. }
  363.  
  364. dowipe()
  365. {
  366.     if(u.ucreamed)  {
  367. #  ifdef DGKMOD
  368.         set_occupation(wipeoff, "wiping off your face", 0);
  369. #  else
  370.         occupation = wipeoff;
  371.         occtxt = "wiping off your face";
  372. #  endif
  373.         return(1);
  374.     }
  375.     pline("Your face is already clean.");
  376.     return(1);
  377. }
  378. # endif
  379. #endif /* KAA && KOPS */
  380.  
  381. /* split obj so that it gets size num */
  382. /* remainder is put in the object structure delivered by this call */
  383. struct obj *
  384. splitobj(obj, num) register struct obj *obj; register int num; {
  385. register struct obj *otmp;
  386.     otmp = newobj(0);
  387.     *otmp = *obj;        /* copies whole structure */
  388.     otmp->o_id = flags.ident++;
  389.     otmp->onamelth = 0;
  390.     obj->quan = num;
  391.     obj->owt = weight(obj);
  392.     otmp->quan -= num;
  393.     otmp->owt = weight(otmp);       /* -= obj->owt ? */
  394.     obj->nobj = otmp;
  395.     if(obj->unpaid) splitbill(obj,otmp);
  396.     return(otmp);
  397. }
  398.  
  399. more_experienced(exp,rexp)
  400. register int exp, rexp;
  401. {
  402.     extern char pl_character[];
  403.  
  404.     u.uexp += exp;
  405.     u.urexp += 4*exp + rexp;
  406.     if(exp) flags.botl = 1;
  407.     if(u.urexp >= ((pl_character[0] == 'W') ? 1000 : 2000))
  408.         flags.beginner = 0;
  409. }
  410.  
  411. set_wounded_legs(side, timex)
  412. register long side;
  413. register int timex;
  414. {
  415.     if(!Wounded_legs || (Wounded_legs & TIMEOUT))
  416.         Wounded_legs |= side + timex;
  417.     else
  418.         Wounded_legs |= side;
  419. }
  420.  
  421. heal_legs()
  422. {
  423.     if(Wounded_legs) {
  424.         if((Wounded_legs & BOTH_SIDES) == BOTH_SIDES)
  425.             pline("Your legs feel somewhat better.");
  426.         else
  427.             pline("Your leg feels somewhat better.");
  428.         Wounded_legs = 0;
  429.     }
  430. }
  431.  
  432. #ifdef SINKS
  433. trycall(obj)
  434. register struct obj *obj;
  435. {
  436.     if(!objects[obj->otyp].oc_name_known &&
  437.        !objects[obj->otyp].oc_uname)
  438.        docall(obj);
  439. }
  440.  
  441. dosinkring(obj)  /* obj is a ring being dropped over a kitchen sink */
  442. register struct obj *obj;
  443. {
  444. register struct obj *otmp,*otmp2;
  445. register short eaten;
  446.     pline("You drop %s down the drain.", doname(obj));
  447.     switch(obj->otyp) {
  448.         case RIN_ADORNMENT:  {
  449.         pline("The faucets flash brightly for a moment.");
  450.         trycall(obj);
  451.         break;
  452.         }
  453.         case RIN_REGENERATION:  {
  454.          pline("The sink looks as good as new.");
  455.         trycall(obj);
  456.         break;
  457.         }
  458.         case RIN_SEARCHING:
  459.         break;
  460.         case RIN_SEE_INVISIBLE:
  461.         break;
  462.         case RIN_STEALTH:  {
  463.         pline("The sink seems to blend into the floor for a moment.");
  464.         trycall(obj);
  465.         break;
  466.         }
  467.         case RIN_LEVITATION:  {
  468.         pline("The sink quivers upward for a moment.");
  469.         trycall(obj);
  470.         break;
  471.         }
  472.         case RIN_POISON_RESISTANCE:
  473.         break;
  474.         case RIN_AGGRAVATE_MONSTER:
  475.         break;
  476.         case RIN_HUNGER:  {
  477.         eaten = 0;
  478.         for(otmp=fobj; otmp; otmp=otmp2) {
  479.             otmp2 = otmp->nobj;
  480.             if(otmp->ox == u.ux && otmp->oy == u.uy)
  481.             if(!Punished ||
  482.                 (otmp->otyp != HEAVY_IRON_BALL && otmp->otyp != IRON_CHAIN)) {
  483.                 eaten++;
  484.                 pline("Suddenly, %s vanishes from the sink!",doname(otmp));
  485.                 delobj(otmp);
  486.             }
  487.         }
  488.         if(eaten)
  489.             trycall(obj);
  490.         break;
  491.         }
  492.         case RIN_FIRE_RESISTANCE:  {
  493.         pline("The hot water faucet flashes brightly for a moment.");
  494.         trycall(obj);
  495.         break;
  496.         }
  497.         case RIN_COLD_RESISTANCE:  {
  498.         pline("The cold water faucet flashes brightly for a moment.");
  499.         trycall(obj);
  500.         break;
  501.         }
  502.         case RIN_PROTECTION_FROM_SHAPE_CHAN:  {
  503.         pline("The sink momentarily looks nothing like a fountain.");
  504.         trycall(obj);
  505.         break;
  506.         }
  507.         case RIN_CONFLICT:
  508.         break;
  509.         case RIN_GAIN_STRENGTH:
  510.         break;
  511.         case RIN_INCREASE_DAMAGE:
  512.         break;
  513.         case RIN_PROTECTION:
  514.         break;
  515.         case RIN_WARNING:  {
  516.         pline("The sink glows white for a moment.");
  517.         trycall(obj);
  518.         break;
  519.         }
  520.         case RIN_TELEPORTATION:    /* fall through */
  521.         case RIN_TELEPORT_CONTROL:    {
  522.         pline("The sink momentarily vanishes.");
  523.         trycall(obj);
  524.         break;
  525.         }
  526.         case RIN_POLYMORPH:     /* fall through */
  527.         case RIN_POLYMORPH_CONTROL:  {
  528.         pline("The sink momentarily looks like a fountain.");
  529.         trycall(obj);
  530.         break;
  531.         }
  532.     }
  533.     if (!rn2(20)) {
  534.         pline("The sink backs up, leaving %s.", doname(obj));
  535.         dropx(obj);
  536.     }
  537.     else
  538.         useup(obj);
  539. }
  540. #endif
  541.